package com.asialjim.wechat.apiservice.executor.handler;

import com.asialjim.wechat.apiservice.exception.UnSupportContentTypeException;
import com.asialjim.wechat.utils.JsonUtils;
import com.asialjim.wechat.utils.XmlUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpResponseException;
import org.apache.http.entity.ContentType;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.util.Objects;

/**
 * <h1><em>ASIAL JIM JAVA DOC</em></h1><hr/>
 * <h2>CLASS DESCRIPTION <i>[ NAME: UTF8ResponseHandler ]</i></h2><strong>
 * <p> 响应结果
 * </strong><p><p><em>Copyright &copy; Asial Jim Co., LTD</em><hr/>
 * @param <T> 响应结果
 * @author Asial Jim &nbsp;&nbsp; <span>Email:<a href="mailto:asialjim@hotmail.com">asialjim@hotmail.com</a> &nbsp;&nbsp; <a href="asialjim@qq.com">asialjim@qq.com</a></span>
 * @version 1.0.0
 * @since 2021/2/28   &nbsp;&nbsp; JDK 8
 */
@Data
@Slf4j
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class UTF8ResponseHandler<T> extends BaseResponseHandler<T> {
    private static final int STATUS_CODE_300 = 300;

    /**
     * <h3>FIELD DESCRIPTION</h3>
     * 响应结果类型
     */
    private Class<T> returnClass;

    /**
     * <h3>FIELD DESCRIPTION</h3>
     * api 响应结果类型
     */
    private ContentType responseContentType;
    private static final String CONTENT_TYPE_NOT_MATCH = "HTTP response content type:[%s] is not match API response content type:[%s]";


    @Override
    public T handleResponse(final HttpResponse response) throws ClientProtocolException, IOException {
        final StatusLine statusLine = response.getStatusLine();
        final HttpEntity entity = response.getEntity();

        if (statusLine.getStatusCode() >= STATUS_CODE_300){
            EntityUtils.consume(entity);
            throw new HttpResponseException(statusLine.getStatusCode(),statusLine.toString());
        }

        if (Objects.isNull(entity)) {return null;}

        String entityStr = EntityUtils.toString(entity, Consts.UTF_8);
        if (StringUtils.isBlank(entityStr)){return null;}
        log.info("\r\n\tUTF-8 HTTP RESPONSE STRING:[{}] HANDLED",entityStr);

        Header contentTypeHeader = entity.getContentType();
        String contentTypeValue = Objects.nonNull(contentTypeHeader)
                                    ? contentTypeHeader.getValue()
                                    : ContentType.WILDCARD.getMimeType();

        ContentType contentType = ContentType.parse(contentTypeValue);

        if (!contentTypeEqual(responseContentType,contentType)){
            throw UnSupportContentTypeException.create(String.format(CONTENT_TYPE_NOT_MATCH,contentType.getMimeType(),responseContentType.getMimeType()));
        }

        if (contentTypeEqual(contentType,ContentType.APPLICATION_JSON)){
            return JsonUtils.toObject(entityStr,returnClass);
        }

        if (contentTypeEqual(contentType,ContentType.APPLICATION_XML)){
            return XmlUtils.xml2Object(entityStr,returnClass);
        }

        if (contentTypeEqual(contentType,ContentType.TEXT_XML)){
            return XmlUtils.xml2Object(entityStr,returnClass);
        }

        if (contentTypeEqual(contentType,ContentType.TEXT_PLAIN)){
            //noinspection unchecked
            return (T) entityStr;
        }

        throw UnSupportContentTypeException.create(contentType.getMimeType());
    }
}
